from fastapi import APIRouter, HTTPException, File, UploadFile, Form, status
from fastapi.responses import JSONResponse
from typing import Dict, Any, Optional, List, Union
import os
import time
import uuid
import json
import base64
from pydantic import BaseModel
import io
import requests
from py_files.config import get_client, select_model
from py_files.get_file_type_prompt import image_to_data_url_by_model, imageurl_by_model, imagepath_file_to_data_url_by_model
from py_files.pdf2imageself import convert_pdf_to_folder_api
import py_files.prompt_dict_def as prompt_dict_dir2
# 创建路由器
image_ocr_router = APIRouter(tags=["图像OCR"])

# 对应路由/image_ocr"
# 固定提示词字典
prompt_dict = {
    "ocr_without_figure":{
        "cn_type": "快速文字识别",
        "system_prompt": "你是有用的助手",
        "user_prompt": "识别图片上的文字,尽量保持原有格式与结构。",
        "system_prompt_second_text_llm": "",
        "user_prompt_second_text_llm": "",
        "description": "处理1章时间约15秒",
        "function_name": ""
    },
    "ocr_pure_text":{
        "cn_type": "文字识别,纯文字，效果可以",
        "system_prompt": "你是有用的助手",
        "user_prompt": prompt_dict_dir2.ocr_prompt_user,
        "system_prompt_second_text_llm": "",
        "user_prompt_second_text_llm": "",
        "description": "精确的文字、图表、公式识别和图片内容解释，处理时间约17秒",
        "function_name": ""
    },
    "ocr":{#        "user_prompt": "对于文字：直接识别；对于图形：进行详细解释；对于表格：保留原本信息与格式；",
        "cn_type": "文字识别,包含图与表",
        "system_prompt": "你是有用的助手",
        "user_prompt": prompt_dict_dir2.ocr_image_comprehend_prompt_user,
        "system_prompt_second_text_llm": "",
        "user_prompt_second_text_llm": "",
        "description": "精确的文字、图表、公式识别和图片内容解释，处理时间约17秒",
        "function_name": ""
    },
    "json": {
        "cn_type": "通用格式",
        "system_prompt": "",
        "user_prompt": "提取图片中的json信息",
        "system_prompt_second_text_llm": "",
        "user_prompt_second_text_llm": "",
        "description": "处理时间约33秒",
        "function_name": "get_json"
    },
    "json_bill": {
        "cn_type": "对账单",
        "system_prompt": "",
        "user_prompt": prompt_dict_dir2.json_bill_prompt_user_omni,
        "system_prompt_second_text_llm": "",
        "user_prompt_second_text_llm": prompt_dict_dir2.bank_statement_prompt_user,
        "description": "处理时间约33秒",
        "function_name": "get_json"
    },
    "json_cn_en_finance": {
        "cn_type": "通用格式_cn_en",
        "system_prompt": """"""
        ,
        "user_prompt": """提取图片中的json信息"""
        ,
        "system_prompt_second_text_llm": prompt_dict_dir2.json_cn_en_finance_prompt_system,
        "user_prompt_second_text_llm": prompt_dict_dir2.json_cn_en_finance_prompt_user,
        "description": "双模型提取处理时间约54秒;提取不全时24秒就结束了；",
        "function_name": "get_json_cn_en"
    },
    "invoice": {
        "cn_type": "发票",
        "system_prompt": "",
        "user_prompt": prompt_dict_dir2.invoice_extraction_user_prompt,
        "description": "发票识别;处理时间约",
        "function_name": "get_invoice"
    }
}

def format_content_to_human_readable(content):
    """
    将包含 JSON 代码块的字符串转换为更符合人类直觉的格式（感觉没啥用）。
    content=completion.choices[0].message.content
    
    参数:
        content (str): 原始内容，可能包含 ```json 标记(去除此标记)。
    
    返回:
        str: 美化后的 JSON 字符串（无代码块标记）。
    """
    # 去除 ```json 和 ``` 标记
    if content.startswith("```json") and content.endswith("```"):
        json_str = content[7:-3].strip()  # 去掉头尾的 ```json 和 ```
    elif content.startswith("```") and content.endswith("```"):
        json_str = content[3:-3].strip()  # 通用处理（非json标记）
    else:
        json_str = content.strip()  # 无标记则直接使用
    
    try:
        # 解析 JSON 并重新格式化为缩进的美观格式
        data = json.loads(json_str)
        formatted_json = json.dumps(data, indent=4, ensure_ascii=False)
        return formatted_json
    except json.JSONDecodeError as e:
        # 如果解析失败，返回原始内容（或抛出异常）
        return f"Invalid JSON: {e}\nOriginal content:\n{content}"
      
# 从URL获取图片内容
async def get_image_from_url(image_url: str) -> bytes:
    """从URL获取图片内容
    
    Args:
        image_url: 图片的URL地址
        
    Returns:
        bytes: 图片的二进制内容
    
    Raises:
        HTTPException: 如果获取图片失败
    """
    try:
        response = requests.get(image_url, timeout=30)
        response.raise_for_status()  # 如果响应状态码不是200，将引发异常
        return response.content
    except requests.RequestException as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"获取图片URL失败: {str(e)}"
        )
        
# 获取图片url符合llm的格式的image_url_data-带{"url"}或不带}
async def get_file_imageUrl_for_llm(file: Optional[UploadFile] = None, image_url: Optional[str] = None, model_name: Optional[str] = None, no_url_model_list = ["qwen_31132_244"]):
    """获取适合于LLM的图片URL格式
    
    Args:
        file: 上传的图片文件 (可选)
        image_url: 图片URL (可选)
        model_name: 模型名称
        no_url_model_list: 不需要url包装的模型列表
        
    Returns:
        适合指定模型的图片URL格式
        
    Raises:
        HTTPException: 当处理图片失败时
    """
    has_file = file is not None and hasattr(file, 'filename') and file.filename
    has_url = image_url is not None and image_url.strip() != ""
    
    # 至少需要提供有效的file或image_url中的一个
    if not has_file and not has_url:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="必须提供有效的file或image_url参数"
        )
      
    # 初始化image_url_data变量
    image_url_data = None
    
    try:
        # 根据模型类型获取兼容的图片url
        if has_file:
            try:
                # 对于文件上传，获取文件内容
                file_content = await file.read()
                if not file_content:  # 检查文件内容是否为空
                    raise ValueError("上传的文件内容为空")
                    
                # 重置文件指针，以便后续可能的读取
                file.file.seek(0)
                
                # 获取文件名和类型信息
                filename = file.filename
                # content_type = file.content_type
                
                # 使用字节IO对象
                with io.BytesIO(file_content) as file_bytes:
                    file_bytes.name = filename  # 添加name属性，以便MIME类型检测
                    image_url_data = imagepath_file_to_data_url_by_model(file_bytes, model_name)
                return image_url_data
            except Exception as file_error:
                # 文件处理错误，检查是否有URL可用
                if has_url:
                    # 回退到使用URL
                    image_url_data = imageurl_by_model(image_url, model_name)
                    return image_url_data
                else:
                    # 没有URL可回退，抛出原始错误
                    raise HTTPException(
                        status_code=status.HTTP_400_BAD_REQUEST,
                        detail=f"处理上传文件时出错: {str(file_error)}"
                    )
        elif has_url:
            # 对于URL，直接使用
            image_url_data = imageurl_by_model(image_url, model_name)
            return image_url_data
        else:
            # 这种情况不应该发生，因为我们已经在前面检查了
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="缺少有效的图片来源"
            )
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"处理图片时出错: {str(e)}"
        )
def get_system_user_prompt(prompt_type: str,prompt_dict=prompt_dict):
    if prompt_type not in prompt_dict:
      raise HTTPException(
          status_code=status.HTTP_400_BAD_REQUEST,
          detail=f"不支持的提示类型：{prompt_type}，可用类型：{list(prompt_dict.keys())}"
      )
    system_prompt = prompt_dict[prompt_type]["system_prompt"]
    user_prompt = prompt_dict[prompt_type]["user_prompt"]
    return system_prompt,user_prompt
  
def llm_process_content(content, client, prompt_type=None, text_model_name="gemma-3-27b-it", prompt_dict=prompt_dict):
  """
  注：content=completion.choices[0].message.content；
  双大模型处理：调用文本大模型处理：多模态大模型得到的json文本；
  优点：能兼容不支持system_prompt的模型；
  
  Args:
    content: 第一个模型的输出内容
    client: OpenAI兼容的客户端
    prompt_type: 提示类型，用于获取相应的提示词
    text_model_name: 文本处理模型名称
    prompt_dict: 提示词字典
    
  Returns:
    处理后的内容字符串
  """
  try:
    print(f"text_llm_process_content 启动，使用模型: {text_model_name}")
    
    # 检查文本模型名称是否有效
    if not text_model_name:
      print("未指定文本模型名称，返回原始内容")
      return content
      
    # 获取文本模型客户端
    try:
      client, internal_model_name = get_client(text_model_name)
      print(f"成功获取文本处理模型 {internal_model_name} 的客户端")
    except Exception as model_error:
      print(f"获取文本处理模型客户端失败: {str(model_error)}，返回原始内容")
      return content
  
    # 设置超时
    timeout = 120
    
    # 检查提示词类型是否有效
    if not prompt_type or prompt_type not in prompt_dict:
      print(f"提示词类型 {prompt_type} 无效或不存在，返回原始内容")
      return content
      
    # 获取提示词
    system_prompt_second_text_llm = prompt_dict[prompt_type].get("system_prompt_second_text_llm", "")
    user_prompt_second_text_llm = prompt_dict[prompt_type].get("user_prompt_second_text_llm", "")
    
    # 检查提示词是否存在
    if not system_prompt_second_text_llm and not user_prompt_second_text_llm:
      print(f"提示词类型 {prompt_type} 没有配置二次处理提示词，返回原始内容")
      return content
    
    # 适配不同模型的消息格式（ # Gemma 模型不支持系统提示词，将系统提示词合并到用户提示词）
    messages = []
    if "gemma" in internal_model_name.lower():
      combined_prompt = ""
      if system_prompt_second_text_llm:
        combined_prompt = f"Instructions: {system_prompt_second_text_llm}\n\n"
      combined_prompt += f"{user_prompt_second_text_llm}\n\n{str(content)}"
      
      messages = [
        {"role": "user", "content": combined_prompt}
      ]
    else:
      # 其他模型使用常规的系统提示词 + 用户提示词格式
      if system_prompt_second_text_llm:
        messages.append({"role": "system", "content": system_prompt_second_text_llm})
      
      messages.append({"role": "user", "content": f"{user_prompt_second_text_llm}\n\n{str(content)}"})
    
    # 检查是否有提示词可用
    if not messages or (len(messages) == 1 and not messages[0]["content"].strip()):
      # 如果没有有效的提示词，直接返回原始内容
      print("没有有效的提示词配置，返回原始内容")
      return content
    
    print(f"向文本模型发送请求...")
    try:
      # 调用API
      completion = client.chat.completions.create(
          model=internal_model_name,
          messages=messages,
          max_tokens=1024,
          stream=False,
          timeout=timeout  # 设置超时时间
      )
      
      processed_content = completion.choices[0].message.content
      print(f"文本模型处理成功")
      return processed_content
    except Exception as api_error:
      print(f"调用文本模型API出错: {str(api_error)}")
      # 如果处理失败，返回原始内容
      return content
  except Exception as e:
    print(f"文本处理过程中发生未捕获的错误: {str(e)}")
    # 如果发生任何错误，返回原始内容
    return content
  
# 处理OCR请求的函数
async def process_ocr_image(
    file: Optional[UploadFile] = None, 
    image_url: Optional[str] = None,
    prompt_type: str = "json", 
    model_name: Optional[str] = None,
    use_second_text_llm: bool = False,
    second_text_llm_model: Optional[str] = None
) -> Dict[str, Any]:
    """处理图片，使用指定的模型和提示类型进行OCR处理
    
    Args:
        file: 上传的图片文件 (可选)
        image_url: 图片URL (可选)
        prompt_type: 提示类型 ("json" 或 "invoice")
        model_name: 模型名称，如果为None则使用默认模型
        use_second_text_llm: 是否使用文本大模型进行二次处理，默认为False
        second_text_llm_model: 用于二次处理的文本大模型名称
        
    Returns:
        Dict: OpenAI兼容的API响应
    """
    try:
        print(f"process_ocr_image...")
        # 如果未指定模型，使用默认模型
        if model_name is None:
            model_name = select_model
            
        # 获取适合模型的图片URL格式 - 使用await调用异步函数
        image_url_data = await get_file_imageUrl_for_llm(file, image_url, model_name)
        # 获取客户端和内部模型名称
        client, internal_model_name = get_client(model_name)
        # 获取提示词 (从原始的prompt_dict中获取)
        system_prompt,user_prompt = get_system_user_prompt(prompt_type)
        # 设置超时
        timeout = 120
        
        # 调用API
        completion = client.chat.completions.create(
            model=internal_model_name,
            messages=[
                # 系统提示词
                {"role": "system", "content": system_prompt},
                # 用户输入（图片+问题）
                {"role": "user", "content": [
                    {"type": "text", "text": user_prompt},
                    {"type": "image_url", "image_url": image_url_data},
                ]},
            ],
            max_tokens=1024,
            stream=False,
            timeout=timeout  # 设置超时时间
        )
        content = completion.choices[0].message.content
        # content=format_content_to_human_readable(content)
        
        # 检查是否需要使用文本处理模型
        # 1. 必须设置use_second_text_llm为True
        # 2. second_text_llm_model必须有值
        # 3. 必须存在相应提示词配置
        # 4. 尝试检查模型是否可用
       
        
        # 检查参数和提示词配置
        if use_second_text_llm and second_text_llm_model and prompt_type in prompt_dict and (
            prompt_dict[prompt_type].get("system_prompt_second_text_llm") or 
            prompt_dict[prompt_type].get("user_prompt_second_text_llm")
        ):
            try:
                # 尝试获取文本模型客户端，检查模型是否可用
                print(f"尝试获取文本模型 {second_text_llm_model} 的客户端")
                second_text_client, _ = get_client(second_text_llm_model)
                print(f"使用文本模型 {second_text_llm_model} 处理内容")
                content = llm_process_content(content, second_text_client, prompt_type, second_text_llm_model)
            except Exception as model_error:
                print(f"文本模型 {second_text_llm_model} 不可用: {str(model_error)}")
                print(f"不使用二次文本处理，保持原始内容")
        
        # 返回OpenAI兼容的API响应格式
        return {
            "id": f"ocr-{str(uuid.uuid4())}",
            "object": "ocr.completion",
            "created": int(time.time()),
            "model": model_name,
            "prompt_type": prompt_type,
            "choices": [
                {
                    "index": 0,
                    "message": {
                        "role": "assistant",
                        "content": content
                    },
                    "finish_reason": completion.choices[0].finish_reason if hasattr(completion.choices[0], 'finish_reason') else "stop"
                }
            ],
            "usage": {
                "prompt_tokens": completion.usage.prompt_tokens if hasattr(completion, 'usage') else 0,
                "completion_tokens": completion.usage.completion_tokens if hasattr(completion, 'usage') else 0,
                "total_tokens": completion.usage.total_tokens if hasattr(completion, 'usage') else 0
            }
        }
    except Exception as e:
        # 捕获所有异常并转换为HTTP异常
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"处理图片时出错: {str(e)}"
        )

# 图像OCR API端点
@image_ocr_router.post("/image_ocr")
async def image_ocr(
    file: Optional[UploadFile] = File(None),
    image_url: Optional[str] = Form(None),
    prompt_type: str = Form("json"),
    model_name: Optional[str] = Form(None),
    use_second_text_llm: bool = Form(False),
    second_text_llm_model: Optional[str] = Form(None)
):
    """
    对图片进行OCR处理
    
    - **file**: 要处理的图片文件 (可选，与image_url至少提供一个)
    - **image_url**: 图片URL地址 (可选，与file至少提供一个)
    - **prompt_type**: 提示类型，默认为 "json"
    - **model_name**: 使用的模型名称，如果为空则使用默认模型
    - **use_second_text_llm**: 是否使用文本大模型进行二次处理，默认为False
    - **second_text_llm_model**: 用于二次处理的文本大模型名称，只有在use_second_text_llm为True且模型可联通时才使用
    """
    result = await process_ocr_image(
        file, 
        image_url, 
        prompt_type, 
        model_name, 
        use_second_text_llm, 
        second_text_llm_model
    )
    return JSONResponse(content=result)

async def process_ocr_image_path(
    file_path: str= None, 
    image_url: Optional[str] = None,
    prompt_type: str = "ocr", 
    model_name: Optional[str] = None,
    use_second_text_llm: bool = False,
    second_text_llm_model: Optional[str] = None
) -> Dict[str, Any]:
    """处理图片，使用指定的模型和提示类型进行OCR处理
    
    Args:
        file_path: 上传的图片文件路径 (可选)
        image_url: 图片URL (可选)
        prompt_type: 提示类型 ("json" 或 "invoice")
        model_name: 模型名称，如果为None则使用默认模型
        use_second_text_llm: 是否使用文本大模型进行二次处理，默认为False
        second_text_llm_model: 用于二次处理的文本大模型名称
        
    Returns:
        Dict: OpenAI兼容的API响应
    """
    try:
       
        # 如果未指定模型，使用默认模型
        if model_name is None:
            model_name = select_model
            
        # 获取适合模型的图片URL格式
        if file_path:
            image_url_data = imagepath_file_to_data_url_by_model(file_path, model_name)
        elif image_url:
            image_url_data = imageurl_by_model(image_url, model_name)
        else:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="必须提供有效的file_path或image_url参数"
            )
            
        # 获取客户端和内部模型名称
        client, internal_model_name = get_client(model_name)
        # 获取提示词 (从原始的prompt_dict中获取)
        system_prompt,user_prompt = get_system_user_prompt(prompt_type)
        # 设置超时
        timeout = 120
        print(f"process_pdf image: file_path:{file_path},prompt_type:{prompt_type},model_name:{model_name},use_second_text_llm:{use_second_text_llm},second_text_llm_model:{second_text_llm_model}")
        # 调用API
        completion = client.chat.completions.create(
            model=internal_model_name,
            messages=[
                # 系统提示词
                {"role": "system", "content": system_prompt},
                # 用户输入（图片+问题）
                {"role": "user", "content": [
                    {"type": "text", "text": user_prompt},
                    {"type": "image_url", "image_url": image_url_data},
                ]},
            ],
            stream=False,
            temperature=0.7,      # 最大限度降低随机性
            top_p=0.9,            # 仅考虑最确定的token
            # frequency_penalty=0.5, # 抑制重复内容
            # presence_penalty=0.5, # 保持关键信息出现频率
            # max_tokens=2000,       # 确保完整输出
            timeout=timeout  # 设置超时时间
        
        )
        content = completion.choices[0].message.content
        # content=format_content_to_human_readable(content)
        
        # 检查是否需要使用文本处理模型
        # 1. 必须设置use_second_text_llm为True
        # 2. second_text_llm_model必须有值
        # 3. 必须存在相应提示词配置
        # 4. 尝试检查模型是否可用
       
        
        # 检查参数和提示词配置
        if use_second_text_llm and second_text_llm_model and prompt_type in prompt_dict and (
            prompt_dict[prompt_type].get("system_prompt_second_text_llm") or 
            prompt_dict[prompt_type].get("user_prompt_second_text_llm")
        ):
            try:
                # 尝试获取文本模型客户端，检查模型是否可用
                print(f"尝试获取文本模型 {second_text_llm_model} 的客户端")
                second_text_client, _ = get_client(second_text_llm_model)
                print(f"使用文本模型 {second_text_llm_model} 处理内容")
                content = llm_process_content(content, second_text_client, prompt_type, second_text_llm_model)
            except Exception as model_error:
                print(f"文本模型 {second_text_llm_model} 不可用: {str(model_error)}")
                print(f"不使用二次文本处理，保持原始内容")
        
        # 返回OpenAI兼容的API响应格式
        return {
            "id": f"ocr-{str(uuid.uuid4())}",
            "object": "ocr.completion",
            "created": int(time.time()),
            "model": model_name,
            "prompt_type": prompt_type,
            "choices": [
                {
                    "index": 0,
                    "message": {
                        "role": "assistant",
                        "content": content
                    },
                    "finish_reason": completion.choices[0].finish_reason if hasattr(completion.choices[0], 'finish_reason') else "stop"
                }
            ],
            "usage": {
                "prompt_tokens": completion.usage.prompt_tokens if hasattr(completion, 'usage') else 0,
                "completion_tokens": completion.usage.completion_tokens if hasattr(completion, 'usage') else 0,
                "total_tokens": completion.usage.total_tokens if hasattr(completion, 'usage') else 0
            }
        }
    except Exception as e:
        # 捕获所有异常并转换为HTTP异常
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"处理图片时出错: {str(e)}"
        )
        
@image_ocr_router.post("/pdf_image_ocr")
async def pdf_image_ocr(
    file: Optional[UploadFile] = File(None),
    image_url: Optional[str] = Form(None),
    prompt_type: str = Form("ocr"),
    model_name: Optional[str] = Form("Qwen/Qwen2.5-Omni-7B"),
    use_second_text_llm: bool = Form(False),
    second_text_llm_model: Optional[str] = Form(None),
    max_image_size: int = Form(1024)  # 添加参数控制图像最大尺寸
):
    """
    对PDF文件进行OCR处理，将PDF转换为图片后逐页处理
    
    - **file**: 要处理的PDF文件 (可选，与image_url至少提供一个)
    - **image_url**: PDF的URL地址 (可选，与file至少提供一个)
    - **prompt_type**: 提示类型，默认为 "ocr"
    - **model_name**: 使用的模型名称，默认为 "Qwen/Qwen2.5-Omni-7B"
    - **use_second_text_llm**: 是否使用文本大模型进行二次处理，默认为False
    - **second_text_llm_model**: 用于二次处理的文本大模型名称，只有在use_second_text_llm为True且模型可联通时才使用
    - **max_image_size**: 图像的最大尺寸（宽或高），默认为1024像素
    """
    # 记录开始时间
    start_time = time.time()
    
    # 检查是否提供了文件
    if not file:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="必须提供PDF文件"
        )
    
    print(f"开始处理PDF文件: {file.filename}")
        
    # 明确传递必要的参数，不使用默认的Query对象
    pdf_response = await convert_pdf_to_folder_api(
        file=file,
        input_dir="",  # 使用默认值
        output_dir="",  # 使用默认值
        dpi=str(300),  # 设置一个合理的DPI值
        fmt="png",  # 使用PNG格式
        first_page=None,
        last_page=None,
        grayscale="false",
        use_pdftocairo="true"
    )
    
    image_paths_list = pdf_response["image_paths"]
    total_images = len(image_paths_list)
    print(f"PDF转换完成，共生成 {total_images} 张图片")
    
    result_list = []
    progress = {}  # 用于存储进度信息
    
    # 导入PIL库用于图像处理
    from PIL import Image
    import os
    
    # 处理每张图片
    for index, image_path in enumerate(image_paths_list):
        # 更新进度信息
        current_page = index + 1
        progress_percent = (current_page / total_images) * 100
        print(f"处理第 {current_page}/{total_images} 张图片 ({progress_percent:.2f}%)")
        
        try:
            # 调整图像大小以避免超出模型上下文长度限制
            resized_image_path = image_path
            try:
                # 打开原始图像
                with Image.open(image_path) as img:
                    # 获取原始尺寸
                    width, height = img.size
                    print(f"原始图像尺寸: {width}x{height}")
                    
                    # 检查是否需要调整大小
                    if width > max_image_size or height > max_image_size:
                        # 计算调整比例
                        ratio = min(max_image_size / width, max_image_size / height)
                        new_width = int(width * ratio)
                        new_height = int(height * ratio)
                        
                        # 调整图像大小
                        resized_img = img.resize((new_width, new_height), Image.LANCZOS)
                        print(f"调整后的图像尺寸: {new_width}x{new_height}")
                        
                        # 保存调整后的图像
                        resized_image_path = f"{os.path.splitext(image_path)[0]}_resized{os.path.splitext(image_path)[1]}"
                        resized_img.save(resized_image_path)
                        print(f"调整后的图像已保存至: {resized_image_path}")
            except Exception as resize_error:
                print(f"调整图像大小时出错: {str(resize_error)}，将使用原始图像")
                resized_image_path = image_path
            
            # 记录单张图片处理开始时间
            image_start_time = time.time()
            
            # 使用调整大小后的图像
            result = await process_ocr_image_path(
                file_path=resized_image_path, 
                image_url=None,  # 我们使用本地文件路径，不需要URL
                prompt_type=prompt_type, 
                model_name=model_name, 
                use_second_text_llm=use_second_text_llm, 
                second_text_llm_model=second_text_llm_model
            )
            
            # 计算单张图片处理时间
            image_process_time = time.time() - image_start_time
            print(f"第 {current_page} 张图片处理完成，耗时 {image_process_time:.2f} 秒")
            
            # 添加进度信息到结果中
            result["progress"] = {
                "current_page": current_page,
                "total_pages": total_images,
                "progress_percent": progress_percent,
                "image_process_time": image_process_time
            }
            
            result_list.append(result)
            
            # 如果创建了调整大小的临时图像，删除它
            if resized_image_path != image_path and os.path.exists(resized_image_path):
                try:
                    os.remove(resized_image_path)
                    print(f"已删除临时调整大小的图像: {resized_image_path}")
                except Exception as del_error:
                    print(f"删除临时图像时出错: {str(del_error)}")
                    
        except Exception as e:
            # 处理单张图片的错误，但继续处理其他图片
            error_message = f"处理图片 {image_path} 时出错: {str(e)}"
            print(error_message)
            result_list.append({
                "error": error_message,
                "image_path": image_path,
                "progress": {
                    "current_page": current_page,
                    "total_pages": total_images,
                    "progress_percent": progress_percent
                }
            })
    
    # 计算总处理时间
    total_process_time = time.time() - start_time
    
    # 创建最终返回结果
    final_result = {
        "results": result_list,
        "summary": {
            "total_images": total_images,
            "processed_images": sum(1 for r in result_list if "error" not in r),
            "failed_images": sum(1 for r in result_list if "error" in r),
            "total_process_time": total_process_time,
            "average_time_per_image": total_process_time / total_images if total_images > 0 else 0,
            "pdf_filename": file.filename,
            "prompt_type": prompt_type,
            "model_name": model_name,
            "use_second_text_llm": use_second_text_llm,
            "second_text_llm_model": second_text_llm_model if use_second_text_llm else None,
            "max_image_size": max_image_size
        }
    }
    
    # 将OCR结果保存为Markdown文件
    try:
        # 创建临时文件夹（如果不存在）
        temp_dir = "uploads/temp_ocr_results"
        os.makedirs(temp_dir, exist_ok=True)
        
        # 生成不重复的文件名
        timestamp = int(time.time())
        file_basename = os.path.splitext(file.filename)[0]
        md_filename = f"{file_basename}_{timestamp}.md"
        md_filepath = os.path.join(temp_dir, md_filename)
        
        # 创建并写入Markdown文件
        with open(md_filepath, "w", encoding="utf-8") as md_file:
            # 写入标题
            md_file.write(f"# OCR 结果: {file.filename}\n\n")
            
            # 写入每页的OCR结果，只包含内容
            for i, result in enumerate(result_list):
                if "error" in result:
                    # 处理错误情况
                    md_file.write(f"## 第 {i+1} 页 (处理失败)\n\n")
                    md_file.write(f"错误信息: {result['error']}\n\n")
                else:
                    # 处理成功情况
                    md_file.write(f"## 第 {i+1} 页\n\n")
                    content = result["choices"][0]["message"]["content"]
                    md_file.write(content)
                    md_file.write("\n\n")
        
        # 将Markdown文件路径添加到返回结果中
        final_result["md_file"] = {
            "filename": md_filename,
            "filepath": md_filepath,
            "absolute_path": os.path.abspath(md_filepath)
        }
        
        print(f"OCR结果已保存到Markdown文件: {md_filepath}")
    except Exception as md_error:
        print(f"保存Markdown文件时出错: {str(md_error)}")
        # 将错误信息添加到返回结果中，但不影响主要功能
        final_result["md_file_error"] = str(md_error)
    
    print(f"PDF处理完成，总耗时 {total_process_time:.2f} 秒，平均每张图片 {total_process_time / total_images if total_images > 0 else 0:.2f} 秒")
    print(f"成功处理 {final_result['summary']['processed_images']} 张图片，失败 {final_result['summary']['failed_images']} 张图片")
    
    return JSONResponse(content=final_result)